package kt.com.bilin.coin.ui.widget

import android.app.Activity
import android.content.Context
import android.content.Intent
import android.net.Uri
import android.os.Build
import android.text.TextUtils
import android.util.AttributeSet
import android.webkit.*
import androidx.fragment.app.FragmentActivity
import com.bilin.coin.BuildConfig
import com.liulishuo.filedownloader.BaseDownloadTask
import com.liulishuo.filedownloader.FileDownloadListener
import com.liulishuo.filedownloader.FileDownloader
import com.umeng.analytics.MobclickAgent
import com.yanzhenjie.permission.AndPermission
import kt.com.bilin.coin.bean.ImageUploadBean
import kt.com.bilin.coin.common.checkAppInstalled
import kt.com.bilin.coin.common.getAppRootPath
import kt.com.bilin.coin.common.startAPP
import kt.com.bilin.coin.common.toastMessageLong
import kt.com.bilin.coin.ui.dialog.LoadingDialog
import kt.com.bilin.coin.ui.dialog.safeDismissDialog
import kt.com.bilin.coin.ui.dialog.safeShowDialog
import kt.com.bilin.coin.ui.dialog.showAlertDialog
import kt.com.bilin.coin.utils.ImageUploadUtils
import kt.com.bilin.coin.utils.Logger
import kt.com.bilin.coin.utils.selectImage
import java.io.File


class BLWebView : WebView {
    constructor(context: Context) : this(context, null)
    constructor(context: Context, attrs: AttributeSet?) : super(context, attrs)

    private val mImageUploadUtils: ImageUploadUtils by lazy { ImageUploadUtils(context as FragmentActivity, "", this::onUploadSuccess) }
    private var mUploadMsg: ValueCallback<Uri>? = null
    private var mFilePathCallback: ValueCallback<Array<Uri>>? = null
    var titleChangeListener: ((title: String) -> Unit)? = null
    private lateinit var mLoadingDialog: LoadingDialog

    init {
        mImageUploadUtils.mOnCancelSuccessListener = this::onUploadCancel
        if (BuildConfig.DEBUG && Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
            setWebContentsDebuggingEnabled(true)
        }
        (context as Activity).runOnUiThread { mLoadingDialog = LoadingDialog(context).apply { setCancelable(false) } }
        settings.apply {
            javaScriptEnabled = true
            domStorageEnabled = true
            loadsImagesAutomatically = true
            useWideViewPort = true
            cacheMode = WebSettings.LOAD_NO_CACHE
            setAppCacheMaxSize(1024 * 1024 * 8.toLong())
            val appCachePath: String = context.cacheDir.absolutePath
            setAppCachePath(appCachePath)
            allowFileAccess = true
            setAppCacheEnabled(true)
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
                mixedContentMode = WebSettings.MIXED_CONTENT_ALWAYS_ALLOW
            }
        }
        class JsInterface {
            @JavascriptInterface
            fun CheckInstall(packageName: String?) {
                Logger.e("CheckInstall")
                if (context.checkAppInstalled(packageName)) {
                    post { loadUrl("javascript:CheckInstall_Return(1)") }
                } else {
                    post { loadUrl("javascript:CheckInstall_Return(0)") }
                }
            }

            @JavascriptInterface
            fun OpenAPP(packageName: String?) {
                Logger.e("OpenAPP")
                context.startAPP(packageName)
            }

            @JavascriptInterface
            fun Browser(url: String?) {
                Logger.e("Browser")
                val uri = Uri.parse(url)
                val intent = Intent(Intent.ACTION_VIEW, uri)
                context.startActivity(intent)
            }

            @JavascriptInterface
            fun startQQConversation(qq: String?) {
                if (context.checkAppInstalled("com.tencent.mobileqq")) {
                    context.startActivity(Intent(Intent.ACTION_VIEW, Uri.parse(qq)))
                } else {
                    "请检查QQ是否可用!".toastMessageLong()
                }
            }

            @android.webkit.JavascriptInterface
            fun download(appUrl: String?, packageName: String?) {
                // 执行下载相关逻辑，优化下载体验
                // 建议机器存在packageName应用直接打开
                // 不存在则使用url下载广告主app
                Logger.e("download==>appUrl:$appUrl<==packageName==>$packageName")
                if (!TextUtils.isEmpty(appUrl)) {
                    if (context.checkAppInstalled(packageName)) {
                        context.startAPP(packageName)
                    } else if (appUrl?.endsWith(".apk") == false) {
                        openInBrowser(appUrl)
                    } else {
                        (context as Activity).runOnUiThread { mLoadingDialog.safeShowDialog() }
                        val savePath = context.getAppRootPath().path + "/gametask.apk"
                        FileDownloader.getImpl().create(appUrl)
                                .setPath(savePath)
                                .setForceReDownload(true)
                                .setListener(object : FileDownloadListener() {
                                    override fun progress(task: BaseDownloadTask, current: Int, total: Int) {
                                        val fp = current.toFloat() / total.toFloat()
                                        val progress = (fp * 100).toInt()
                                        (context as Activity).runOnUiThread { mLoadingDialog.setProgress(progress) }
                                    }

                                    override fun blockComplete(task: BaseDownloadTask) {
                                        (context as Activity).runOnUiThread {
                                            mLoadingDialog.safeDismissDialog()
                                            Logger.e("<==savepath==>$savePath")
                                            "下载成功".toastMessageLong()
                                            AndPermission.with(context)
                                                    .install()
                                                    .file(File(savePath))
                                                    .onGranted { }
                                                    .onDenied { "安装失败".toastMessageLong() }
                                                    .start()
                                        }
                                    }

                                    override fun error(task: BaseDownloadTask, e: Throwable) {
                                        MobclickAgent.reportError(context, e)
                                        (context as Activity).runOnUiThread { mLoadingDialog.safeDismissDialog() }
                                    }

                                    override fun completed(task: BaseDownloadTask) = (context as Activity).runOnUiThread { mLoadingDialog.safeDismissDialog() }
                                    override fun pending(task: BaseDownloadTask, soFarBytes: Int, totalBytes: Int) {}
                                    override fun connected(task: BaseDownloadTask, etag: String, isContinue: Boolean, soFarBytes: Int, totalBytes: Int) {}
                                    override fun retry(task: BaseDownloadTask, ex: Throwable, retryingTimes: Int, soFarBytes: Int) {}
                                    override fun paused(task: BaseDownloadTask, soFarBytes: Int, totalBytes: Int) {}
                                    override fun warn(task: BaseDownloadTask) {}
                                }).start()
                    }
                }
            }

            fun openInBrowser(url: String) {
                Logger.e("url==>$url")
                context.startActivity(Intent(Intent.ACTION_VIEW, Uri.parse(url)))
            }
        }
        addJavascriptInterface(JsInterface(), "partyMethod")
        addJavascriptInterface(JsInterface(), "android")
        webViewClient = object : WebViewClient() {
            override fun shouldOverrideUrlLoading(view: WebView, url: String): Boolean {
                if ("nvp://finish".startsWith(url)) {
                    (context as Activity).finish()
                } else {
                    view.loadUrl(url)
                }
                return true
            }

            override fun onPageFinished(view: WebView, url: String) {
                super.onPageFinished(view, url)
                if (TextUtils.isEmpty(title) && view.title != null) titleChangeListener?.invoke(view.title)
            }
        }
        webChromeClient = object : WebChromeClient() {
            override fun onJsAlert(view: WebView?, url: String?, message: String?, result: JsResult?): Boolean {
                (context as Activity).showAlertDialog {
                    message(message = message ?: "")
                    positiveButton { result?.confirm() }
                }
                return true
            }

            // For Android 3.0+
            fun openFileChooser(uploadMsg: ValueCallback<Uri>, acceptType: String) {
                Logger.e("openFileChooser 1")
                mUploadMsg = uploadMsg
                selectImage()
            }

            // For Android < 3.0
            fun openFileChooser(uploadMsgs: ValueCallback<Uri>) {
                Logger.e("openFileChooser 2")
                mUploadMsg = uploadMsgs
                selectImage()
            }

            // For Android  > 4.1.1
            fun openFileChooser(uploadMsg: ValueCallback<Uri>, acceptType: String, capture: String) {
                Logger.e("openFileChooser 3")
                mUploadMsg = uploadMsg
                selectImage()
            }

            // For Android  >= 5.0
            override fun onShowFileChooser(webView: WebView, filePathCallback: ValueCallback<Array<Uri>>, fileChooserParams: FileChooserParams): Boolean {
                Logger.e("openFileChooser 4:$filePathCallback")
                mFilePathCallback = filePathCallback
                selectImage()
                return true
            }
        }
    }

    private fun selectImage() {
        mImageUploadUtils.selectImage {
            isUp = false
            isMultipleChoice = false
        }
    }

    private fun onUploadSuccess(imageUploads: MutableList<ImageUploadBean>) {
        if (imageUploads.isNotEmpty()) {
            val uri = Uri.fromFile(File(imageUploads[0].filePath))
            mUploadMsg?.onReceiveValue(uri)
            mUploadMsg = null
            mFilePathCallback?.onReceiveValue(arrayOf(uri))
            mFilePathCallback = null
        } else {
            onUploadCancel()
        }
    }

    private fun onUploadCancel() {
        mUploadMsg?.onReceiveValue(null)
        mUploadMsg = null
        mFilePathCallback?.onReceiveValue(null)
        mFilePathCallback = null
    }

}